package com.bolang.onlycode.demo.MyThread;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 精确的唤醒下一个线程
 */
public class LoopABCconditionlock {
    private int num;
    private static Lock lock = new ReentrantLock(true);
    private static Condition condition1 = lock.newCondition();
    private static Condition condition2 = lock.newCondition();
    private static Condition condition3 = lock.newCondition();
    private static Condition condition4 = lock.newCondition();
    private static Condition condition5 = lock.newCondition();
    private static Condition condition6 = lock.newCondition();
    private static Condition condition7 = lock.newCondition();

    public static void main(String[] args) throws NoSuchFieldException {
        LoopABCconditionlock loopABCconditionlock = new LoopABCconditionlock();
        new Thread(() -> {
            loopABCconditionlock.print(0, condition1, condition2);
        }, "A").start();

        new Thread(() -> {
            loopABCconditionlock.print(1, condition2, condition3);
        }, "B").start();
        new Thread(() -> {
            loopABCconditionlock.print(2, condition3, condition1);
        }, "C").start();

        new Thread(()->{
            loopABCconditionlock.print(3,condition4,condition5);
        },"D").start();
        new Thread(()->{
            loopABCconditionlock.print(4,condition5,condition6);
        },"E").start();
        new Thread(()->{
            loopABCconditionlock.print(5,condition6,condition7);
        },"F").start();
        new Thread(()->{
            loopABCconditionlock.print(6,condition7,condition1);
        },"G").start();
//        new Thread(()->{
//            loopABCconditionlock.print(7,condition8,condition9);
//        },"H").start();
//        new Thread(()->{
//            loopABCconditionlock.print(8,condition9,condition10);
//        },"I").start();
//        new Thread(()->{
//            loopABCconditionlock.print(9,condition10,condition11);
//        },"G").start();
//        new Thread(()->{
//            loopABCconditionlock.print(10,condition11,condition1);
//        },"K").start();
    }

    public void print(int targeNum, Condition currentCondition, Condition nextCondition) {
        for (int i = 0; i < 3; ) {
            // 获得锁的线程进来发现自己不满足执行条件，会将本线程移到等待队列里面
            // BC线程没竞争到锁的现在被添加到等待队列里面了
            // 问题是他的锁释放了吗，释放了，释放锁的核心代码在于setState(0);
            // lock.unlock和condition.await()方法底层都调用了release()方法，
            // 这个方法不管state是几,都会修改state为0，
            // lock默认使用非公平锁，在无参构造函数中new了一个非公平锁

            lock.lock();
            System.out.println(Thread.currentThread().getName() + "线程第" + i + "次获取到锁");
            try {
                while (num % 7 != targeNum) {
                    System.out.println(Thread.currentThread().getName() + "线程第" + i + "次被阻塞住了");
                    currentCondition.await();
                }

                num++;
                i++;
                System.out.println(Thread.currentThread().getName());
                nextCondition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
//                System.out.println(Thread.currentThread().getName()+"线程释放了锁");
                lock.unlock();

            }
        }

    }
}
